package com.zhai.domain.strategy.service.rule.tree.factory.engine.impl;

import com.zhai.domain.strategy.model.valobj.*;
import com.zhai.domain.strategy.service.rule.tree.ILogicTreeNode;
import com.zhai.domain.strategy.service.rule.tree.factory.DefaultTreeFactory;
import com.zhai.domain.strategy.service.rule.tree.factory.engine.IDecisionTreeEngine;
import lombok.extern.slf4j.Slf4j;

import java.util.Date;
import java.util.List;
import java.util.Map;

/**
 * @Description: 决策树引擎
 * @ClassName: DecisionTreeEngine
 * @Author: zhaiyongxin
 * @Date: 2025/2/5 15:12
 * @Version: 1.0
 */
@Slf4j
public class DecisionTreeEngine implements IDecisionTreeEngine {

    private final Map<String, ILogicTreeNode> logicTreeNodeGroup;

    private final RuleTreeVO ruleTreeVO;

    public DecisionTreeEngine(Map<String, ILogicTreeNode> logicTreeNodeGroup, RuleTreeVO ruleTreeVO) {
        this.logicTreeNodeGroup = logicTreeNodeGroup;
        this.ruleTreeVO = ruleTreeVO;
    }

    @Override
    public DefaultTreeFactory.StrategyAwardVO process(String userId, Long strategyId, Integer awardId, Date endDateTime) {
        //要返回的奖品信息
        DefaultTreeFactory.StrategyAwardVO strategyAwardVO = null;
        //1.获取根节点信息
        String nextNode = ruleTreeVO.getTreeRootRuleNode();
        Map<String, RuleTreeNodeVO> treeNodeMap = ruleTreeVO.getTreeNodeMap();
        RuleTreeNodeVO ruleTreeNode = treeNodeMap.get(nextNode);


        //2.当下一节点为空时停止循环，返回结果
        while (nextNode != null) {
            ILogicTreeNode logicTreeNode = logicTreeNodeGroup.get(nextNode);
            // ruleValue值说明：ruleValue在规则树中代表着不同树节点对应的特殊规则值，比如在次数锁节点中代表着解锁次数，在默认积分节点中代表着区间值
            String ruleValue = ruleTreeNode.getRuleValue();

            DefaultTreeFactory.TreeActionEntity logicEntity = logicTreeNode.logic(userId, strategyId, awardId, endDateTime, ruleValue);
            //当前策略计算出来的结果值：放行|接管
            RuleLogicCheckTypeVO ruleLogicCheckType = logicEntity.getRuleLogicCheckType();
            strategyAwardVO = logicEntity.getStrategyAwardVO();
            log.info("决策树引擎【{}】treeId:{} node:{} code:{}", ruleTreeVO.getTreeName(), ruleTreeVO.getTreeId(), nextNode, ruleLogicCheckType.getCode());

            //计算下个节点到哪

            List<RuleTreeNodeLineVO> treeNodeLineList = ruleTreeNode.getTreeNodeLineVOList();
            nextNode = nextNode(ruleLogicCheckType.getCode(), treeNodeLineList);
            ruleTreeNode = treeNodeMap.get(nextNode);

        }
        return strategyAwardVO;
    }


    public String nextNode(String matterValue, List<RuleTreeNodeLineVO> treeNodeLineVOList) {
        if (treeNodeLineVOList == null || treeNodeLineVOList.size() == 0) {return null;}
        for (RuleTreeNodeLineVO ruleTreeNodeLineVO : treeNodeLineVOList) {
            if (decisionLogic(matterValue, ruleTreeNodeLineVO)){
                return ruleTreeNodeLineVO.getRuleNodeTo();
            }
        }
        return null;
    }

    /**
     * 判断物料与预定值是否相等
     * @param matterValue
     * @param nodeLine
     * @return
     */
    public boolean decisionLogic(String matterValue, RuleTreeNodeLineVO nodeLine) {
        switch (nodeLine.getRuleLimitType()) {
            case EQUAL:
                return matterValue.equals(nodeLine.getRuleLimitValue().getCode());
            // 以下规则暂时不需要实现
            case GT:
            case LT:
            case GE:
            case LE:
            default:
                return false;
        }
    }
}
